﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RayDen.RayEngine.Core.Types;

namespace RayDen.RayEngine.Engines.MCMC.PSS
{
    public partial class PssPathSampler
    {
        public override void Splat(SampleBuffer sampleBuffer)
        {
            var pssSampler = (PsMltSampler)this.pathIntegrator.Sampler;
            if (pssSampler.BurnInPhase)
            {

                if (!Radiance.IsBlack())
                {
                    pssSampler.AddContribution(ref Radiance);
                    pssSampler.Accept(this.Sample);
                    oldContribution = Radiance;
                    oldx = Sample.imageX;
                    oldy = Sample.imageY;
                }
                sampleBuffer.SplatSample(this.Sample.imageX, this.Sample.imageY, ref this.Radiance);
                InitPath(this.pathIntegrator);
                return;
            }
            this.Sample.MutationsCount++;

            if (!Radiance.IsBlack())
            {
                if (oldContribution.IsBlack())//this.Sample.LargeStep || 
                {
                    pssSampler.Accept(this.Sample);
                    pssSampler.AddContribution(ref Radiance);
                    oldContribution = Radiance;
                    oldx = Sample.imageX;
                    oldy = Sample.imageY;
                    sampleBuffer.SplatSample(this.Sample.imageX, this.Sample.imageY, ref this.Radiance);
                }
                else
                {
                    var x = oldContribution.y();
                    var y = Radiance.y();
                    var a = Math.Min(1f, y / x);
                    if (a > pssSampler.NextFloat())
                    {
                        oldContribution = Radiance;
                        oldx = Sample.imageX;
                        oldy = Sample.imageY;
                        pssSampler.Accept(this.Sample);
                        largeStep = false;
                    }
                    else
                    {
                        pssSampler.Reject(this.Sample);
                    }

                    var b = pssSampler.B / (pssSampler.MaxMutations);//* pssSampler.B.y()
                    var yContrib = (b) * a * (oldContribution / oldContribution.y());
                    var xContrib = (b) * (1f - a) * (Radiance / Radiance.y());
                    sampleBuffer.SplatSample(this.Sample.imageX, this.Sample.imageY, ref xContrib);
                    sampleBuffer.SplatSample(this.oldx, this.oldy, ref yContrib);
                }
            }
            else
            {
                pssSampler.Reject(Sample);
            }
            InitPath(this.pathIntegrator);
        }

    }
}
